<template><div><!-- [[toc]] -->
<h2 id="_01-理解代码" tabindex="-1"><a class="header-anchor" href="#_01-理解代码" aria-hidden="true">#</a> 01-理解代码</h2>
<ul>
<li><code v-pre>词法分析</code>是把程序分割成一个个 Token 的过程，可以通过构造有限自动机来实现。<br>
<code v-pre>语法分析</code>是把程序的结构识别出来，并形成一棵便于计算机处理的抽象语法树，可以用递归下降的算法来实现。<br>
<code v-pre>语义分析</code>是消除语义模糊，生成一些属性信息，让计算机能够依据这些信息生成目标代码</li>
</ul>
<h2 id="_02-正则文法和有限自动机" tabindex="-1"><a class="header-anchor" href="#_02-正则文法和有限自动机" aria-hidden="true">#</a> 02-正则文法和有限自动机</h2>
<ul>
<li>
<p><code v-pre>[]</code>代表匹配方括号中的字符之一<br>
<code v-pre>[abc]</code>匹配 a 或 b 或 c<br>
<code v-pre>[a-z]</code>匹配从 a 到 z 的任何一个字符<br>
<code v-pre>*</code>匹配 0 个或者多个前面的元素<br>
<code v-pre>+</code>匹配 1 个或者多个前面的元素<br>
<code v-pre>''</code>严格匹配单引号里面的所有字符，如：<code v-pre>'if'</code>或者<code v-pre>'int'</code></p>
</li>
<li>
<p><code v-pre>Java</code>的正则表达式工具在<code v-pre>java.util.regex</code>包中，在其<code v-pre>Javadoc</code>中有详细的规则说明</p>
</li>
<li>
<p><code v-pre>标识符</code>为什么第一个字符必须是字母？
因为这是为了制作编译器的方便，如果一个变量以数字开头，那么分析器就必须在遇到第一个或第二个英文字符的时候回溯来确定是否是数字、变量名还是词法错误，这时候变成了二型文法。二型文法分析器的好处是支持回溯和递归语法，但缺点是状态机相比正则文法，其状态会大大增加，而且代码写起来更困难，考虑到词法分析部分只是用来断字，我们实在是没必要为了支持变量名以数字开头这么一个小功能，而让整个词法分析部分用二型文法来写，所以，Java 语言变量名拒绝使用数字开头这种方式。</p>
</li>
<li>
<p>我们可以声明一个<code v-pre>intA</code>这样的变量，而不会跟<code v-pre>int</code>关键字冲突，是因为当第一个字符是<code v-pre>i</code>的时候，我们让它进入一个特殊的状态，接下来如果它遇到<code v-pre>n</code>和<code v-pre>t</code>，就会判断是关键字<code v-pre>int</code>，但到这里还没有结束，如果后续的字符还有其他的字母和数字，它又变成了普通的标识符。</p>
</li>
<li>
<p>实现一个词法分析器，首先写出每个词法的正则表达式，并画出有限自动机，之后，只要用代码标表示这种状态迁移过程即可。</p>
</li>
</ul>
<h2 id="_37-云编程" tabindex="-1"><a class="header-anchor" href="#_37-云编程" aria-hidden="true">#</a> 37-云编程</h2>
<ul>
<li>
<p><code v-pre>云IDE</code>的优势：</p>
<ol>
<li>易于管理的编程环境
<ol>
<li>这一点，会给编程教育这个领域，提供很大的帮助。因为，学习编程的人能够根据需要，打开不同的编程环境，立即投入学习。反之，如果要先做很多复杂的配置才能开始学习，学习热情就会减退，一些人也就因此止步了。其实，在软件开发团队中，你经常会看到这样一个现象：新加入项目组的成员，要花很长的时间，才能把开发环境搭建起来。因为他们需要安装各种软件，开通各种账号等等。那么，如果是基于<code v-pre>云IDE</code>开发的，这些麻烦都可以省掉。</li>
</ol>
</li>
<li>支持跨平台编程</li>
<li>更强的计算能力
<ol>
<li>有些软件的编译非常消耗 <code v-pre>CPU</code> ，比如，完整编译 <code v-pre>LLVM</code> 可能需要一两个小时，而充分利用服务器的资源可以让编译速度更快。如果你从事<code v-pre>AI</code>方面的开发，体会会更深，<code v-pre>AI</code> 需要大量的算力，并且 <code v-pre>GPU</code> 和 <code v-pre>TPU</code> 都很昂贵，我们很难自己去搭建这样的开发环境。而基于云开发，你可以按需使用云上的 <code v-pre>GPU</code>、<code v-pre>TPU</code> 和 <code v-pre>CPU</code> 的计算能力。</li>
</ol>
</li>
<li>有利于开发过程的管理</li>
<li>更好的团队协作</li>
</ol>
</li>
<li>
<p>微软的<code v-pre>Visual Studio</code>支持直接使用<code v-pre>Azure</code>云上的资源。</p>
</li>
<li>
<p>程序员最早是直接编写机器码，<code v-pre>指令</code>和<code v-pre>寄存器</code>都要直接用 <code v-pre>0101</code> 来表示。后来，<code v-pre>冯·诺依曼</code>的一个学生，发明了用助记符的方法（也就是汇编语言）简化机器码的编写。用汇编语言编程的时候，你仍然要使用指令和寄存器，但可以通过名称来引用，比如，用 ·pushq %rbp· 这样的汇编指令来表示机器码 ·0x55·。这就增加了一个抽象层次，用名称代替了指令和寄存器的编码。而高级语言出现后，我们不再直接访问寄存器，而是使用<code v-pre>变量</code>、<code v-pre>过程</code>和<code v-pre>作用域</code>，抽象程度进一步增加。</p>
</li>
</ul>
<ul>
<li><a href="https://www.infoq.cn/article/fA42rfjV*dYGAvRANFqE" target="_blank" rel="noopener noreferrer">云原生<ExternalLinkIcon/></a></li>
</ul>
<h2 id="_38-元编程" tabindex="-1"><a class="header-anchor" href="#_38-元编程" aria-hidden="true">#</a> 38-元编程</h2>
<ul>
<li><code v-pre>元编程</code>是只指程序操纵程序的能力，也就是用程序修改或者生成程序，也有人用另外的表述方式，认为具有元编程能力的语言，能够把程序当做数据来处理，典型的代表是 Lisp 语言。</li>
<li>编译技术的本质就是把程序当做数据来处理，所以你可以用编译技术的视角考察各种语言是如何实现元编程的。</li>
<li>采用元编程技术，要保证所实现的软件是容易学习、维护良好的。</li>
<li>好的<code v-pre>DSL</code>能够抽象出领域的特点，不需要使用者关心下层的技术细节。<code v-pre>DSL</code>可以用元编程技术实现，也可以用我们本课程的编译技术实现。</li>
</ul>
</div></template>


